﻿/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is tyzoh.jp code.
 *
 * The Initial Developer of the Original Code is Kazutaka Kurihara.
 * Portions created by the Initial Developer are Copyright (C) 2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** */
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;

namespace MRUManager
{
    public interface IMRUClient
    {
        bool OpenMRUFile(string fileName);
    }

    public class FileMRUManager
    {
        private Form ownerForm;                 // owner form

        //private MenuItem menuItemMRU;           // Recent Files menu item
        //private MenuItem menuItemParent;        // Recent Files menu item parent
        private ToolStripMenuItem menuItemMRU;           // Recent Files menu item
        private ToolStripDropDownButton menuItemParent;        // Recent Files menu item parent

        private string registryPath;            // Registry path (file path) to keep MRU list

        private int maxNumberOfFiles = 10;      // maximum number of files in MRU list

        private int maxDisplayLength = 40;      // maximum length of file name for display

        private string currentDirectory;        // current directory

        private List<string> mruList;

        public FileMRUManager()
        {
            mruList = new List<string>();
        }

        public int MaxDisplayNameLength
        {
            set
            {
                maxDisplayLength = value;

                if (maxDisplayLength < 10)
                    maxDisplayLength = 10;
            }

            get
            {
                return maxDisplayLength;
            }
        }

        public int MaxMRULength
        {
            set
            {
                maxNumberOfFiles = value;

                if (maxNumberOfFiles < 1)
                    maxNumberOfFiles = 1;

                if (mruList.Count > maxNumberOfFiles)
                    mruList.RemoveRange(maxNumberOfFiles - 1, mruList.Count - maxNumberOfFiles);
            }

            get
            {
                return maxNumberOfFiles;
            }
        }

        public string CurrentDir
        {
            set
            {
                currentDirectory = value;
            }

            get
            {
                return currentDirectory;
            }
        }

        //public void Initialize(Form owner, MenuItem mruItem, string regPath)
        public void Initialize(Form owner, ToolStripMenuItem mruItem,ToolStripDropDownButton parent, string regPath)
        {
            ownerForm = owner;

            if (!(owner is IMRUClient))
            {
                throw new Exception(
                    "FileMRUManager: Owner form doesn't implement IMRUClient interface");
            }

            menuItemMRU = mruItem;

            try
            {
                menuItemParent = parent;
            }
            catch
            {
            }

            if (menuItemParent == null)
            {
                throw new Exception(
                    "FileMRUManager: Cannot find parent of MRU menu item");
            }

            registryPath = regPath;

            currentDirectory = Directory.GetCurrentDirectory();

            menuItemParent.DropDownOpened += new EventHandler(this.OnMRUParentPopup);

            ownerForm.Closing += new System.ComponentModel.CancelEventHandler(OnOwnerClosing);

            LoadMRU();
        }

        public void Add(string file)
        {
            Remove(file);

            if (mruList.Count == maxNumberOfFiles)
                mruList.RemoveAt(maxNumberOfFiles - 1);

            mruList.Insert(0, file);
        }
        public void Remove(string file)
        {
            mruList.Remove(file);
        }

        public bool OpenDefault()
        {
            if (mruList.Count == 0) return false;

            try
            {
                string s = mruList[0];
                if (s.Length > 0)
                {
                    return ((IMRUClient)ownerForm).OpenMRUFile(s);
                }
                return false;
            }
            catch (Exception ex)
            {
                return false;
            }

        }


        private void OnMRUParentPopup(object sender, EventArgs e)
        {
            if (menuItemMRU.DropDownItems.Count > 0)
            {
                menuItemMRU.DropDownItems.Clear();
            }

            if (mruList.Count == 0)
            {
                menuItemMRU.Enabled = false;
                return;
            }

            menuItemMRU.Enabled = true;

            ToolStripMenuItem item;

            List<string>.Enumerator myEnum = mruList.GetEnumerator();

            while (myEnum.MoveNext())
            {
                item = new ToolStripMenuItem(GetDisplayName(myEnum.Current));

                item.Click += new EventHandler(this.OnMRUClicked);

                menuItemMRU.DropDownItems.Add(item);
            }
        }

        private void OnMRUClicked(object sender, EventArgs e)
        {
            string s;

            try
            {
                ToolStripMenuItem item = (ToolStripMenuItem)sender;

                if (item != null)
                {
                    s = mruList[menuItemMRU.DropDownItems.IndexOf(item)];

                    if (s.Length > 0)
                    {
                        ((IMRUClient)ownerForm).OpenMRUFile(s);
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }

        private void OnOwnerClosing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            int i, n;

            try
            {
                if (File.Exists(registryPath)) File.Delete(registryPath);
                StreamWriter sw = new StreamWriter(registryPath);
                n = mruList.Count;
                for (i = 0; i < n; i++)
                {
                    sw.WriteLine(mruList[i]);
                }
                sw.Flush();
                sw.Close();
            }
            catch (Exception ex)
            {
            }
        }

        private void LoadMRU()
        {
            string s;

            try
            {
                mruList.Clear();

                if (File.Exists(registryPath))
                {
                    StreamReader sr = new StreamReader(registryPath);

                    for (int i = 0; i < maxNumberOfFiles; i++)
                    {
                        if (sr.EndOfStream) break;
                        s = sr.ReadLine();
                        mruList.Add(s);
                    }
                    sr.Close();
                }
            }
            catch (Exception ex)
            {
            }
        }

        private string GetDisplayName(string fullName)
        {
            FileInfo fileInfo = new FileInfo(fullName);

            if (fileInfo.DirectoryName == currentDirectory)
                return GetShortDisplayName(fileInfo.Name, maxDisplayLength);

            return GetShortDisplayName(fullName, maxDisplayLength);
        }

        private string GetShortDisplayName(string longName, int maxLen)
        {
            int sP = (longName.Length > maxLen) ? maxLen : longName.Length;
            sP = longName.Length - sP;
            return longName.Substring(sP);
        }

    }
}
